﻿//     Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Gateway.Configuration;

namespace Microsoft.Gateway.RulesConfigurator.ConfigComparitors
{
    class RulesComparitor : IEqualityComparer<RulesConfiguration>
    {
        public bool Equals(RulesConfiguration lhs, RulesConfiguration rhs)
        {
            return lhs.SafeEquals(rhs, (x, y) =>
                lhs.Roles.Count == rhs.Roles.Count &&
                lhs.Roles.Keys
                    .OrderBy(key => key, StringComparer.OrdinalIgnoreCase)
                    .SequenceEqual(y.Roles.Keys.OrderBy(key => key, StringComparer.OrdinalIgnoreCase)) &&
                lhs.Roles
                    .OrderBy(role => role.Key, StringComparer.OrdinalIgnoreCase)
                    .Select(role => role.Value)
                    .SequenceEqual(rhs.Roles
                            .OrderBy(role => role.Key, StringComparer.OrdinalIgnoreCase)
                            .Select(role => role.Value),
                        new RoleComparitor()));
        }

        public int GetHashCode(RulesConfiguration obj)
        {
            throw new NotImplementedException();
        }

        class RoleComparitor : IEqualityComparer<Role>
        {
            public bool Equals(Role lhs, Role rhs)
            {
                return lhs.SafeEquals(rhs, (x, y) =>
                    String.Equals(x.Segment, y.Segment, StringComparison.OrdinalIgnoreCase) &&
                    x.Treatment == y.Treatment &&
                    x.Action == y.Action &&
                    x.Flights.SafeEquals(y.Flights, (l, r) => l.SequenceEqual(r, new FlightComparitor())) &&
                    x.Target.SafeEquals(y.Target, (l, r) => l.SequenceEqual(r, new TargetRouteComparitor())) &&
                    String.Equals(lhs.TargetBasePath, rhs.TargetBasePath, StringComparison.OrdinalIgnoreCase)
                    );
            }

            public int GetHashCode(Role obj)
            {
                throw new NotImplementedException();
            }
        }

        class FlightComparitor : IEqualityComparer<Flight>
        {
            public bool Equals(Flight lhs, Flight rhs)
            {
                return lhs.SafeEquals(rhs, (x, y) =>              
                        String.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase) &&                        
                        x.SourceIP.SafeEquals(y.SourceIP, (l, r) => l.SequenceEqual(r, StringComparer.OrdinalIgnoreCase)) &&
                        x.User.SafeEquals(y.User, (l, r) => l.SequenceEqual(r, StringComparer.OrdinalIgnoreCase)) &&
                        x.Tenant.SafeEquals(y.Tenant, (l, r) => l.SequenceEqual(r, StringComparer.OrdinalIgnoreCase)) &&
                        x.Target.SafeEquals(y.Target, (l, r) => l.SequenceEqual(r, new TargetRouteComparitor())) &&
                        x.DomainName.SafeEquals(y.DomainName, (l, r) => l.SequenceEqual(r, StringComparer.OrdinalIgnoreCase))
                        );    
            }

            public int GetHashCode(Flight obj)
            {
                throw new NotImplementedException();
            }
        }

        class TargetRouteComparitor : IEqualityComparer<TargetRoute>
        {
            public bool Equals(TargetRoute lhs, TargetRoute rhs)
            {
                return lhs.SafeEquals(rhs, (x, y) =>
                        x.Weight == y.Weight && 
                        string.Equals(x.Redirect, y.Redirect, StringComparison.OrdinalIgnoreCase));
            }

            public int GetHashCode(TargetRoute obj)
            {
                throw new NotImplementedException();
            }
        }
    }
}
